﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace uz.control
{
    public partial class UzTreeView : UserControl
    {
        public UzTreeView()
        {
            InitializeComponent();

            MouseWheel += new MouseEventHandler(UzTreeView_MouseWheel);

            Nodes = new UzTreeNodeCollection(this);

            ResizeRedraw = true;
            //for (int i = 0; i < 5; i++)
            //{
            //    TestTreeNode node = new TestTreeNode();
            //    node.Text = i.ToString();
            //    Nodes.Add(node);
            //    node.CreateTestNode(2);
            //}
            
        }



        void UzTreeView_MouseWheel(object sender, MouseEventArgs e)
        {
            int c = e.Delta / 120;
            UzTreeNode node;
            if (c < 0)
            {
                for (int i = 0; i > c; i--)
                {
                    node = FirstDisplayNode.GetNextVisibleNode();
                    if (node != null)
                    {
                        FirstDisplayNode = node;
                    }
                }
            }
            else
            {
                for (int i = 0; i < c; i++)
                {
                    node = FirstDisplayNode.GetPrevVisibleNode();
                    if (node != null)
                    {
                        FirstDisplayNode = node;
                    }
                }
            }
            this.Refresh();
        }

        #region 子节点缩进宽度：Indent
        /// <summary>
        /// 子节点缩进宽度
        /// </summary>
        private int _Indent = 20;
        /// <summary>
        /// 子节点缩进宽度
        /// </summary>
        public int Indent
        {
            get { return _Indent; }
            set { _Indent = value; }
        }
        #endregion

        #region 操作手柄区域宽度：HandleAreaWidth
        /// <summary>
        /// 操作手柄区域宽度
        /// </summary>
        private int _HandleAreaWidth = 20;
        /// <summary>
        /// 操作手柄区域宽度
        /// </summary>
        public int HandleAreaWidth
        {
            get { return _HandleAreaWidth; }
            set { _HandleAreaWidth = value; }
        }
        #endregion

        #region 第一个要绘制的节点：FirstDisplayNode
        /// <summary>
        /// 第一个要绘制的节点
        /// </summary>
        private UzTreeNode _FirstDisplayNode = null;
        /// <summary>
        /// 第一个要绘制的节点
        /// </summary>
        private UzTreeNode FirstDisplayNode
        {
            get 
            {
                if (_FirstDisplayNode == null && Nodes.Count > 0)
                {
                    _FirstDisplayNode = Nodes[0];
                }

                return _FirstDisplayNode; 
            }
            set 
            { 
                _FirstDisplayNode = value; 
            }
        }
        #endregion

        #region 子节点集合：Nodes
        /// <summary>
        /// 子节点集合
        /// </summary>
        public UzTreeNodeCollection Nodes
        {
            get;
            set;
        }
        #endregion

        #region 默认节点高度：ItemHeight
        /// <summary>
        /// 默认节点高度
        /// </summary>
        private int _ItemHeight = 20;
        /// <summary>
        /// 默认节点高度
        /// </summary>
        public int ItemHeight
        {
            get { return _ItemHeight; }
            set { _ItemHeight = value; }
        }
        #endregion

        /// <summary>
        /// 鼠标当前移动坐标
        /// </summary>
        public Point CurrentMouseMovePoint { get; set; }

        /// <summary>
        /// 鼠标当前点击坐标
        /// </summary>
        public Point CurrentMouseDownPoint { get; set; }

        /// <summary>
        /// 鼠标当前释放坐标
        /// </summary>
        public Point CurrentMouseUpPoint { get; set; }

        /// <summary>
        /// OnPaint方法重载
        /// </summary>
        /// <param name="e">绘制事件参数</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            if (FirstDisplayNode == null)
            {
                return;
            }

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed;

            UzTreeNode node = FirstDisplayNode.GetPrevVisibleNode();
            if (node != null)
            {
                node.DrawNode(e, Bounds, new Rectangle(0, 0, Width, FirstDisplayNode.Height));
            }


            FirstDisplayNode.Paint(e, Bounds, new Rectangle(0, 0, Width, FirstDisplayNode.Height));

            timer.Stop();
            Console.WriteLine(timer.ElapsedMilliseconds);
        }

        /// <summary>
        /// 击中测试
        /// </summary>
        /// <param name="pt">要测试的坐标</param>
        /// <returns>测试结果</returns>
        public UzTreeNode HitTest(Point pt)
        {
            int y = 0;
            UzTreeNode node = FirstDisplayNode;

            while (node != null && y - node.Height < Height)
            {
                if ( pt.Y - y < node.Height)
                {
                    break;
                }
                if (node.IsVisible == true)
                {
                    y += node.Height;
                }
                node = node.GetNextVisibleNode();
            }
            return node;
        }
        
        #region 鼠标及键盘
        protected override void OnMouseDown(MouseEventArgs e)
        {
            CurrentMouseDownPoint = e.Location;

            UzTreeNode node = HitTest(e.Location);
            if (node != null && node.ProcessMouseDown(e) == true)
            {
                Refresh();
                return;
            }

            if (SelectedNode != null && SelectedNode.IsEdit == true)
            {
                SelectedNode.IsEdit = false;
            }

            base.OnMouseDown(e);

            Refresh();
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            CurrentMouseMovePoint = e.Location;
            //UzTreeNode node = HitTest(e.Location);
            //if (node != null && node.ProcessMouseMove(e) == true)
            //{
            //    return;
            //}

            base.OnMouseMove(e);

            //Refresh();
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            CurrentMouseUpPoint = e.Location;
            UzTreeNode node = HitTest(e.Location);
            if (node != null && node.ProcessMouseUp(e) == true)
            {
                return;
            }

            base.OnMouseUp(e);

            Refresh();
        }

        protected override bool IsInputKey(System.Windows.Forms.Keys keyData)
        {
            base.IsInputKey(keyData);
            return true;
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if (SelectedNode != null)
            {
                if (SelectedNode.ProcessKeyDown(e) == true)
                {
                    Refresh();
                    return;
                }
            }

            base.OnKeyDown(e);

            if (e.KeyCode == Keys.Down)
            {
                MoveNext();
            }else if (e.KeyCode == Keys.Up)
            {
                MovePrev();
            }else if (e.KeyCode == Keys.Left)
            {
                if (SelectedNode != null)
                {
                    if (SelectedNode.IsExpanded == true && SelectedNode.Nodes.Count > 0)
                    {
                        SelectedNode.Collapse();
                    }else if (SelectedNode.Parent != null)
                    {
                        SelectedNode.Parent.Collapse();
                        SelectedNode = SelectedNode.Parent;
                    }
                }
            }
            else if (e.KeyCode == Keys.Right)
            {
                if (SelectedNode != null)
                {
                    SelectedNode.Expand();
                }
            }

            Refresh();
           
        }

        public void MovePrev()
        {
            if (Nodes.Count == 0)
            {
                return;
            }

            if (SelectedNode == null)
            {
                SelectedNode = FirstDisplayNode;
                return;
            }

            UzTreeNode node = SelectedNode.GetPrevVisibleNode();

            if (node != null)
            {
                SelectedNode = node;
            }
            return;
        }

        public void MoveNext()
        {
            if (Nodes.Count == 0)
            {
                return;
            }

            if (SelectedNode == null)
            {
                SelectedNode = FirstDisplayNode;
                return;
            }

            UzTreeNode node = SelectedNode.GetNextVisibleNode();

            if (node != null)
            {
                SelectedNode = node;
            }
            return;
        }
        protected override void OnKeyUp(KeyEventArgs e)
        {
            base.OnKeyUp(e);

            Refresh();
        }
        #endregion


        /// <summary>
        /// 获得节点选择时的背景色
        /// </summary>
        public Color NodeSelectedBackColor
        {
            get 
            {
                return Color.AliceBlue;
            }
        }

        /// <summary>
        /// 获得节点选择时的前景色
        /// </summary>
        public Color NodeSelectedForeColor
        {
            get 
            {
                return ControlPaint.Light(ForeColor);
            }
        }

        /// <summary>
        /// 节点边框的颜色
        /// </summary>
        private Color _NodeBorderColor = Color.Green;
        /// <summary>
        /// 节点边框的颜色
        /// </summary>
        public Color NodeBorderColor
        {
            get { return _NodeBorderColor; }
            set { _NodeBorderColor = value; }
        }

        /// <summary>
        /// 当前选择的节点
        /// </summary>
        private UzTreeNode _SelectedNode = null;
        /// <summary>
        /// 当前选择的节点
        /// </summary>
        public UzTreeNode SelectedNode
        {
            get { return _SelectedNode; }
            set 
            {
                UzTreeNode oldNode = _SelectedNode;
                _SelectedNode = value;

                if (oldNode != null && oldNode != value)
                {
                    oldNode.IsSelected = false;
                }

                if (_SelectedNode == null)
                {
                    return;
                }

                _SelectedNode.IsSelected = true;

                if (GetMoveFlg(_SelectedNode, FirstDisplayNode) == true)
                {
                    UzTreeNode node = _SelectedNode;
                    int h = Height - node.Height;
                    while (true)
                    {
                        if (h <= 0)
                        {
                            FirstDisplayNode = node;
                            break;
                        }

                        node = node.GetPrevVisibleNode();

                        if (node == null)
                        {
                            break;
                        }

                        if (node == FirstDisplayNode)
                        {
                            return;
                        }

                        h -= node.Height;
                    }


                }
                else
                {
                    FirstDisplayNode = _SelectedNode;
                }

            }
        }

        private bool GetMoveFlg(UzTreeNode left,UzTreeNode right)
        {
            Dictionary<UzTreeNode, UzTreeNode> dic = new Dictionary<UzTreeNode, UzTreeNode>();

            UzTreeNode node = left;
            UzTreeNode RootNode = new UzTreeNode();
            UzTreeNode KeyNode = null;

            while (node != null)
            {
                if (node.Parent == null)
                {
                    KeyNode = RootNode;
                }
                else
                {
                    KeyNode = node.Parent;
                }
                dic.Add(KeyNode, node);
                node = node.Parent;
            }

            node = right;

            while (node != null)
            {
                if (node.Parent == null)
                {
                    KeyNode = RootNode;
                }
                else
                {
                    KeyNode = node.Parent;
                }

                if (dic.ContainsKey(KeyNode) == true)
                {
                    if (dic[KeyNode].Index < node.Index)
                    {
                        return false;
                    }
                    else if (dic[KeyNode].Index > node.Index)
                    {
                        return true;
                    }
                    else
                    {
                        if(left.Leave <= right.Leave)
                        {
                            return false;
                        }else
                        {
                            return true;
                        }
                    }
                }

                node = node.Parent;
            }

            return true;


        }

        /// <summary>
        /// 当前正在编辑的控件
        /// </summary>
        public UzTreeNode CurrentEditedNode { get; set; }

    }
}
